package com.stlm2.dems.pingxxpay.service;


import com.pingplusplus.exception.APIConnectionException;
import com.pingplusplus.exception.APIException;
import com.pingplusplus.exception.AuthenticationException;
import com.pingplusplus.exception.InvalidRequestException;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Event;
import com.stlm2.core.base.BaseDao;
import com.stlm2.core.base.impl.BaseServiceImpl;
import com.stlm2.dems.entity.FlowSource;
import com.stlm2.dems.pingxxpay.dao.OrderPayDao;
import com.stlm2.dems.pingxxpay.entity.OrderPay;
import com.stlm2.dems.pingxxpay.query.OrderPayQuery;
import com.stlm2.dems.recharge.dao.RechargeDao;
import com.stlm2.dems.entity.OrderState;
import com.stlm2.dems.entity.PayChannel;
import com.stlm2.dems.recharge.entity.Recharge;
import com.stlm2.dems.recharge.service.RechargeService;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("orderPayService")
@Transactional(rollbackForClassName = {"java.lang.Exception"}, propagation = Propagation.REQUIRED)
public class OrderPayService extends BaseServiceImpl<OrderPay> {
    private static Logger logger = LoggerFactory.getLogger(OrderPayService.class);
    @Resource
    private OrderPayDao orderPayDao;
    @Resource
    private RechargeDao rechargeDao;
    @Resource
    private RechargeService rechargeService;


    @Override
    protected BaseDao<OrderPay> getDao() {
        return orderPayDao;
    }




    public boolean webhooksCharge(Event event) {//ping++ 支付回调

        Map metadata = null;
        String orderId = null;
        Map obj = (Map) event.getData().get("object");
        if (obj.get("order_no") != null)
            orderId = obj.get("order_no").toString();
        if (obj.get("metadata") != null) {
            metadata = (Map) obj.get("metadata");
        }

        boolean paid = false;
        if (orderId == null) {
            return paid;
        }

        if ("charge.succeeded".equals(event.getType())) {
            if (obj.get("paid") != null) {
                paid = "true".equals(obj.get("paid").toString());
            }
            OrderPayQuery orderPayQuery = orderPayDao.getMapper(OrderPayQuery.class);
            OrderPay orderPay = orderPayQuery.getByChargeId(obj.get("id").toString());
            if (orderPay == null) {
                logger.info("orderPay 错误：{}", obj.get("id").toString());
                return false;
            }

            if (paid) {


                FlowSource fundsSource = FlowSource.getByIntValue(NumberUtils.toInt(orderId.substring(0, 2)));
                if (FlowSource.Buy.equals(fundsSource)) {//购买订单回调处理
                    Recharge order=rechargeDao.getByCode(orderId);

                    PayChannel payChannel = null;
                    if (obj.get("channel").toString().equals("alipay_wap")) {
                        order.setPayChannel(PayChannel.alipay_wap);
                        payChannel = PayChannel.alipay_wap;
                    } else if (obj.get("channel").toString().equals("alipay")) {
                        order.setPayChannel(PayChannel.alipay_app);
                        payChannel = PayChannel.alipay_app;
                    } else if (obj.get("channel").toString().equals("wx")) {
                        order.setPayChannel(PayChannel.pingxx_wx);
                        payChannel = PayChannel.pingxx_wx;
                    } else if (obj.get("channel").toString().equals("wx_pub")) {
                        order.setPayChannel(PayChannel.wx_pub);
                        payChannel = PayChannel.wx_pub;
                    } else if (obj.get("channel").toString().equals("wx_wap")) {
                        order.setPayChannel(PayChannel.wx_wap);
                        payChannel = PayChannel.wx_wap;
                    }else if (obj.get("channel").toString().equals("alipay_pc_direct")) {
                        order.setPayChannel(PayChannel.alipay_pc_direct);
                        payChannel = PayChannel.alipay_pc_direct;
                    }

                    if (order != null && OrderState.Create.equals(order.getOrderState())) {
                        rechargeDao.modify(order);
                        Recharge recharge = rechargeService.pay(order, obj.get("transaction_no").toString(),PayChannel.alipay_wap);
                        if (recharge != null && OrderState.Payment.equals(recharge.getOrderState())) {
                            orderPay.setState(1);
                            orderPayDao.modify(orderPay);
                            return true;
                        } else {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }} else {//支付失败
                orderPay.setState(-1);
                orderPayDao.modify(orderPay);
                return false;
            }

        }
        return paid;
    }

    //购买订单支付
    public Charge createBuyCharge(String openid, PayChannel payChannel, Recharge order, String appId, String remoteAddr, String rootUrl) {
        Map<String, Object> chargeParams = new HashMap<String, Object>();
        //long data = new Date().getTime()/1000+86400;
        long data = new Date().getTime()/1000+7200;
        chargeParams.put("time_expire",data);
        Map<String, String> extra = new HashMap<String, String>();

        if (payChannel.equals(PayChannel.alipay_wap)) {
            order.setPayChannel(PayChannel.alipay_wap);
            chargeParams.put("channel", "alipay_wap");

            extra.put("success_url", rootUrl + "/m/html/pay_success_alipay_v1.html");
            extra.put("cancel_url", rootUrl + "/m/html/pay_fail_v1.html");

        } else if (payChannel.equals(PayChannel.alipay_app)) {
            order.setPayChannel(PayChannel.alipay_app);
            chargeParams.put("channel", "alipay");
        } else if (payChannel.equals(PayChannel.pingxx_wx)) {
            order.setPayChannel(PayChannel.pingxx_wx);
            chargeParams.put("channel", "wx");
        } else if (payChannel.equals(PayChannel.wx_pub)) {
            order.setPayChannel(PayChannel.wx_pub);
            chargeParams.put("channel", "wx_pub");
            extra.put("open_id", openid);
        } else if(payChannel.equals(PayChannel.wx_wap)){
              //微信网页支付
            order.setPayChannel(PayChannel.wx_wap);
            chargeParams.put("channel", "wx_wap");
            //正式平台要用的
            extra.put("result_url", rootUrl + "/m/html/pay_success_alipay_v1.html");

            /*支付宝PC端*/
        }else if(payChannel.equals(PayChannel.alipay_pc_direct)){
            order.setPayChannel(PayChannel.alipay_pc_direct);
            chargeParams.put("channel", "alipay_pc_direct");

            extra.put("success_url", rootUrl + "/pc/html/pay_sucess.html");
           // extra.put("cancel_url", rootUrl + "/m/html/pay_fail_v1.html");

        }
        rechargeDao.modify(order);
        chargeParams.put("extra", extra);
        chargeParams.put("order_no", order.getCode());
        chargeParams.put("amount", order.getMoney());
        Map<String, String> app = new HashMap<String, String>();
        app.put("id", appId);
        chargeParams.put("app", app);
        chargeParams.put("currency", "cny");
        chargeParams.put("client_ip", remoteAddr);
        chargeParams.put("subject", order.getCode());
        chargeParams.put("body",  "余额充值");


        Charge charge = null;
        try {
            charge = Charge.create(chargeParams);
            OrderPayQuery orderPayQuery = orderPayDao.getMapper(OrderPayQuery.class);
            OrderPay orderPay = orderPayQuery.getByChargeId(charge.getId());

            if (orderPay == null) {
                orderPay = new OrderPay();
                orderPay.setChargeId(charge.getId());
                orderPay.setOrderCode(order.getCode());
                orderPay.setType(payChannel.getIntValue());
                orderPay.setState(0);
                orderPay.setType(payChannel.getIntValue());
                orderPay.setCreateTime(new Date());
                orderPayDao.add(orderPay);
            }


        } catch (AuthenticationException e) {
            logger.error(e.toString() + "code:" + order.getCode());
            System.out.println("AuthenticationException:"+e.toString());
        } catch (InvalidRequestException e) {
            logger.error(e.toString() + "code:" + order.getCode());
            System.out.println("InvalidRequestException:"+e.toString());
        } catch (APIConnectionException e) {
            logger.error(e.toString() + "code:" + order.getCode());
            System.out.println("APIConnectionException:"+e.toString());
        } catch (APIException e) {
            logger.error(e.toString() + "code:" + order.getCode());
            System.out.println("APIException:"+e.toString());
        }
        return charge;
    }



    //现金充值订单
    public Charge createMoneyRechargeCharge(String openid, PayChannel payChannel, Recharge recharge, String appId, String remoteAddr, String rootUrl) {

        Map<String, Object> chargeParams = new HashMap<String, Object>();

        Map<String, String> extra = new HashMap<String, String>();

        if (payChannel.equals(PayChannel.alipay_wap)) {
            recharge.setPayChannel(PayChannel.alipay_wap);
            chargeParams.put("channel", "alipay_wap");
            //extra.put("success_url", rootUrl + "/m/html/pay_success.html?orderid=" + recharge.getCode() + "_" + recharge.getMoney());
            extra.put("success_url", rootUrl);//临时路径，上面是真实的。
            extra.put("cancel_url", rootUrl + "/m/html/pay_cancel.html?orderid=" + recharge.getCode() + "_" + recharge.getMoney());
        } else if (payChannel.equals(PayChannel.alipay_app)) {
            recharge.setPayChannel(PayChannel.alipay_app);
            chargeParams.put("channel", "alipay");
        } else if (payChannel.equals(PayChannel.pingxx_wx)) {
            recharge.setPayChannel(PayChannel.pingxx_wx);
            chargeParams.put("channel", "wx");
        } else if (payChannel.equals(PayChannel.wx_pub)) {
            recharge.setPayChannel(PayChannel.wx_pub);
            chargeParams.put("channel", "wx_pub");
            extra.put("open_id", openid);
        }

        rechargeDao.modify(recharge);

        chargeParams.put("extra", extra);

        chargeParams.put("order_no", recharge.getCode());
        chargeParams.put("amount", recharge.getMoney());
        Map<String, String> app = new HashMap<String, String>();
        app.put("id", appId);
        chargeParams.put("app", app);
        chargeParams.put("currency", "cny");
        chargeParams.put("client_ip", remoteAddr);
        chargeParams.put("subject", recharge.getCode());
        chargeParams.put("body", recharge.getUserId() + "现金充值");

        Charge charge = null;
        try {
            charge = Charge.create(chargeParams);
            OrderPayQuery orderPayQuery = orderPayDao.getMapper(OrderPayQuery.class);
            OrderPay orderPay = orderPayQuery.getByChargeId(charge.getId());

            if (orderPay == null) {
                orderPay = new OrderPay();
                orderPay.setChargeId(charge.getId());
                orderPay.setOrderCode(recharge.getCode());
                orderPay.setType(1);
                orderPay.setState(0);
                orderPay.setCreateTime(new Date());
                orderPayDao.add(orderPay);
            }
        } catch (AuthenticationException e) {
            logger.error(e.toString() + "code:" + recharge.getCode());
        } catch (InvalidRequestException e) {
            logger.error(e.toString() + "code:" + recharge.getCode());
        } catch (APIConnectionException e) {
            logger.error(e.toString() + "code:" + recharge.getCode());
        } catch (APIException e) {
            logger.error(e.toString() + "code:" + recharge.getCode());
        }
        return charge;
    }



    /*
    * s
    * */
      public  long getCountFromOrderPayByCodeChannel(Map<String,Object> map){
          return  orderPayDao.getCountFromOrderPayByCodeChannel(map);
      }
    /*
    * s   获取对象
    *
    * */
    public OrderPay getOrderPayFromOrderPayByCodeChannel(Map<String,Object> map){
        return  orderPayDao.getOrderPayFromOrderPayByCodeChannel(map);
    }

    public List<OrderPay> getOrderPayFromOrderPayByState(Map<String,Object> map){
        return  orderPayDao.getOrderPayFromOrderPayByState(map);
    }
    public List<OrderPay>  getOrderPaysByTimeAndCodeAndState(Map<String,Object> map){
        return  orderPayDao.getOrderPaysByTimeAndCodeAndState(map);
    }

    public OrderPay getByCode(String code) {
        return orderPayDao.getByCode(code);
    }

        /*public void pingxxCheckPay(String apiKey) {//定时任务调用检查订单支付状态

        Pingpp.apiKey = apiKey;

        OrderPayQuery orderPayQuery = orderPayDao.getMapper(OrderPayQuery.class);
        Map t = new HashMap();

        t.put("state", "0");
        Date cancelTime = Convert.beforeMinute(new Date(), 1);
        t.put("createTime", cancelTime);

        Map map = new HashMap();
        map.put("t", t);
        List<OrderPay> list = orderPayQuery.query(map);
        for (OrderPay op : list) {

            try {
           Charge charge = Charge.retrieve(op.getChargeId());
                if (charge != null) {
                    if (charge.getPaid()) {
                        PayChannel payChannel = null;
                        if (charge.getChannel().toString().equals("alipay_wap")) {//支付宝手机网页支付
                            payChannel = PayChannel.pingxx_alipay_wap;
                        } else if (charge.getChannel().equals("alipay")) {//支付宝app支付
                            payChannel = PayChannel.pingxx_alipay;
                        } else if (charge.getChannel().equals("wx")) {//微信app支付
                            payChannel = PayChannel.pingxx_wx;
                        } else if (charge.getChannel().equals("wx_pub")) {//微信公众号支付
                            payChannel = PayChannel.pingxx_wx_pub;
                        } else if(charge.getChannel().equals("wx_wap")){//微信公网页支付
                            payChannel = PayChannel.wx_wap;
                        }else if (charge.getChannel().equals("alipay_pc_direct")) {//支付宝即时到帐支付，即支付宝PC网页支付
                            payChannel = PayChannel.alipay_pc_direct;
                        }

                        FundsSource fundsSource = FundsSource.getByIntValue(NumberUtils.toInt(charge.getOrderNo().substring(0, 2)));
                        *//*检查购买未回调订单 fcy*//*
                        if (FundsSource.Buy.equals(fundsSource)) {
                            PurchaseOrder order = purchaseOrderService.getByCode(charge.getOrderNo());
                            order.setPayChannel(payChannel);
                            purchaseOrderDao.modify(order);
                            if (order != null && OrderState.Create.equals(order.getOrderState())) {
                                order = goodsOrderService.pay(order, payChannel, charge.getTransactionNo());
                                if (order != null && OrderState.Payment.equals(order.getOrderState())) {
                                    op.setState(1);
                                    orderPayDao.modify(op);
                                    logger.info("/pingxx/pay_order_id:{} payChannel{} transaction_no{} 支付成功 pingxxCheckPay", charge.getOrderNo(), charge.getChannel(), charge.getTransactionNo());
                                }
                            }
                            *//*检查申请未回调订单 fcy*//*
                        } else if (FundsSource.DealerApply.equals(fundsSource)) {
                            DealerApply apply = dealerApplyService.getByCode(charge.getOrderNo());
                            apply.setPayChannel(payChannel);
                            dealerApplyDao.modify(apply);

                            if (apply != null && OrderState.Create.equals(apply.getOrderState())) {
                                apply = dealerApplyService.pay(apply, charge.getTransactionNo(), payChannel, new Date());
                                if (apply != null && OrderState.Payment.equals(apply.getOrderState())) {
                                    op.setState(1);
                                    orderPayDao.modify(op);
                                    logger.info("/pingxx/pay_order_id:{} payChannel{} transaction_no{} 支付成功 pingxxCheckPay", charge.getOrderNo(), charge.getChannel(), charge.getTransactionNo());
                                }
                            }
                        *//*检查升级未回调订单  fcy*//*
                        }else if(FundsSource.RiseApply.equals(fundsSource)){
                            DealerRiseApply apply = dealerRiseApplyService.getByCode(charge.getOrderNo());
                            apply.setPayChannel(payChannel);
                            dealerRiseApplyDao.modify(apply);

                            if (apply != null && OrderState.Create.equals(apply.getOrderState())) {
                                apply = dealerRiseApplyService.pay(apply, charge.getTransactionNo(), payChannel, new Date());
                                if (apply != null && OrderState.Payment.equals(apply.getOrderState())) {
                                    op.setState(1);
                                    orderPayDao.modify(op);
                                    logger.info("/pingxx/pay_order_id:{} payChannel{} transaction_no{} 支付成功 pingxxCheckPay", charge.getOrderNo(), charge.getChannel(), charge.getTransactionNo());
                                }
                            }
                        }
                    } else {//支付失败
                        op.setState(-1);
                        orderPayDao.modify(op);
                    }
                } else {
                    op.setState(-2);
                    orderPayDao.modify(op);
                    logger.info("chargenull {}", "code:" + op.getOrderCode() + "ChargeId:" + op.getChargeId());
                }
            } catch (AuthenticationException e) {
                logger.info("pingxxCheckPay {}", e.toString() + "code:" + op.getOrderCode() + "ChargeId:" + op.getChargeId());
            } catch (InvalidRequestException e) {
                logger.info("pingxxCheckPay {}", e.toString() + "code:" + op.getOrderCode() + "ChargeId:" + op.getChargeId());
            } catch (APIConnectionException e) {
                logger.info("pingxxCheckPay {}", e.toString() + "code:" + op.getOrderCode() + "ChargeId:" + op.getChargeId());
            } catch (APIException e) {
                logger.info("pingxxCheckPay {}", e.toString() + "code:" + op.getOrderCode() + "ChargeId:" + op.getChargeId());
            }
        }

    }*/
}